
#include "userConfig.h"
#include "Serial.h"
#include <xc.h>
#include <libpic30.h>
#include <stdlib.h>
int __psv__ __attribute__((space(eedata), aligned(_EE_ROW))) EETerminationVoltage;
int __psv__ __attribute__((space(eedata), aligned(_EE_ROW))) EEChargeCurrent;
int __psv__ __attribute__((space(eedata), aligned(_EE_ROW))) EETemperatureThreshold;
int __psv__ __attribute__((space(eedata), aligned(_EE_ROW))) EECANAddress;
int __psv__ __attribute__((space(eedata), aligned(_EE_ROW))) EEMasterMode;
int __psv__ __attribute__((space(eedata), aligned(_EE_ROW))) EEInternalNodeChargeCount;
int __psv__ __attribute__((space(eedata), aligned(_EE_ROW))) EEExternalNodeChargeCount;


static int TerminationVoltage;
static int ChargeCurrent;
static int TemperatureThreshold;
static unsigned char CANAddress;
static int MasterMode;
static int InternalNodeChargeCount;
static int ExternalNodeChargeCount;

static int IsEEPROMValid();
static void SetVariablesFromEEPROM();
static void SetDefaultVariables();
static void WriteEEPROMValue(_prog_addressT destination, int value);

void InitializeUserConfig()
{
    if(IsEEPROMValid())
    {
        SetVariablesFromEEPROM();
    }
    else
    {
        SetDefaultVariables();
    }
}

int IsEEPROMValid()
{
    return EETerminationVoltage != 0xffff;
}

void SetVariablesFromEEPROM()
{
    TerminationVoltage = EETerminationVoltage;
    ChargeCurrent = EEChargeCurrent;
    TemperatureThreshold = EETemperatureThreshold;
    CANAddress = EECANAddress;
    MasterMode = EEMasterMode;
    InternalNodeChargeCount = EEInternalNodeChargeCount;
    ExternalNodeChargeCount = EEExternalNodeChargeCount;
}

void SetDefaultVariables()
{
    SetTerminationVoltage(2800);
    SetChargeCurrent(300);
    SetTemperatureThreshold(20);
    SetCANAddress(0xf0);
    SetMasterMode(1);
    SetInternalNodeChargeCount(1);
    SetExternalNodeChargeCount(1);
}

void PrintUserConfig()
{
    PutString("User Config is:\r");
    PutString("Termination Voltage: ");
    char buffer[10];
    itoa(buffer, TerminationVoltage, 10);
    PutString(buffer);
    PutString("\rCharge Current: ");
    itoa(buffer, ChargeCurrent, 10);
    PutString(buffer);
    PutString("\rTemperature Threshold: ");
    itoa(buffer, TemperatureThreshold, 10);
    PutString(buffer);
    PutString("\r CAN Address: ");
    itoa(buffer, CANAddress, 10);
    PutString(buffer);
    PutString("\rMaster Mode: ");
    if(MasterMode)
    {
        PutString("Master");
    }
    else
    {
        PutString("Slave");
    }
    PutString("\rInternal Node Charge Count: ");
    itoa(buffer, InternalNodeChargeCount, 10);
    PutString(buffer);
    PutString("\rExternal Node Charge Count: ");
    itoa(buffer, ExternalNodeChargeCount, 10);
    PutString(buffer);
    Putchar('\r');
    Putchar('\r');
}

void WriteEEPROMValue(_prog_addressT destination, int value)
{
    _erase_eedata(destination, _EE_WORD);
    _wait_eedata();
    _write_eedata_word(destination, value);
    _wait_eedata();
}

void SetTerminationVoltage(int voltage)
{
    TerminationVoltage = voltage;
    WriteEEPROMValue(__builtin_tbladdress(&EETerminationVoltage), voltage);
}

int GetTerminationVoltage()
{
    return TerminationVoltage;
}

void SetChargeCurrent(int current)
{
    ChargeCurrent = current;
    WriteEEPROMValue(__builtin_tbladdress(&EEChargeCurrent), current);
}

int GetCurrentCommand()
{
    return ChargeCurrent;
}

void SetTemperatureThreshold(int temperature)
{
    TemperatureThreshold = temperature;
    WriteEEPROMValue(__builtin_tbladdress(&EETemperatureThreshold), temperature);
}

int GetTemperatureThreshold()
{
    return TemperatureThreshold;
}

void SetCANAddress(unsigned char address)
{
    CANAddress = address;
    WriteEEPROMValue(__builtin_tbladdress(&EECANAddress), address);
}

unsigned char GetCANAddress()
{
    return CANAddress;
}

void SetMasterMode(int master)
{
    MasterMode = master;
    WriteEEPROMValue(__builtin_tbladdress(&EEMasterMode), master);
}

int GetMasterMode()
{
    return MasterMode;
}

void SetInternalNodeChargeCount(int count)
{
    InternalNodeChargeCount = count;
    WriteEEPROMValue(__builtin_tbladdress(&EEInternalNodeChargeCount), count);
}

int GetInternalNodeChargeCount()
{
    return InternalNodeChargeCount;
}

void SetExternalNodeChargeCount(int count)
{
    ExternalNodeChargeCount = count;
    WriteEEPROMValue(__builtin_tbladdress(&EEExternalNodeChargeCount), count);
}

int GetExternalNodeChargeCount()
{
    return ExternalNodeChargeCount;
}
